package com.chuck.basic.boot.undertow;

import io.undertow.connector.ByteBufferPool;
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.xnio.OptionMap;
import org.xnio.Options;
import org.xnio.Xnio;
import org.xnio.XnioWorker;

import java.io.IOException;

/**
 * 默认情况下，Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器，可以将 Web 服务器切换到 Undertow 来提高应用性能，Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器
 * · Untertow 的特点：
 * · 轻量级：它是一个 Web 服务器，但不像传统的 Web 服务器有容器概念，它由两个核心 Jar 包组成，加载一个 Web 应用可以小于 10MB 内存
 * · Servlet3.1 支持：它提供了对 Servlet3.1 的支持
 * · WebSocket 支持：对 Web Socket 完全支持，用以满足 Web 应用巨大数量的客户端
 * · 嵌套性：它不需要容器，只需通过 API 即可快速搭建 Web 服务
 */
public class UndertowServerFactoryCustomizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        UndertowDeploymentInfoCustomizer undertowDeploymentInfoCustomizer = deploymentInfo -> {
            WebSocketDeploymentInfo info = (WebSocketDeploymentInfo) deploymentInfo.getServletContextAttributes().get(WebSocketDeploymentInfo.ATTRIBUTE_NAME);
            XnioWorker worker = getXnioWorker();
            ByteBufferPool buffers = new DefaultByteBufferPool(Boolean.getBoolean("io.undertow.websockets.direct-buffers"), 1024, 100, 12);
            info.setWorker(worker);
            info.setBuffers(buffers);
        };
        factory.addDeploymentInfoCustomizers(undertowDeploymentInfoCustomizer);
    }

    private XnioWorker getXnioWorker(){
        XnioWorker xnioWorker = null;
        try {
            xnioWorker = Xnio.getInstance().createWorker(OptionMap.create(Options.THREAD_DAEMON,true));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xnioWorker;
    }
}
